home *** CD-ROM | disk | FTP | other *** search
- /* cvgo.c
- * adventurer motion routine moveme()
- *************************************************************************/
-
- #include <stdio.h>
- #include "cvobj.h"
- #include "cvocab.h"
- #include "cvlocs.h"
- #include "cvmisc.h"
- #include "cvorcs.h"
- #include "random.h"
-
- extern struct cvobj *lastobj; /* cvmain.c */
-
- static void
- wrongway(verb) int verb ;
- { if ((verb == FIND) || (verb == INVENT)) {rspeak(59); return; }
- if (verb <= ENTER) {rspeak(9); return; }
- if ((verb == HOPE)
- || (verb == BANIS)
- || (verb == MISFO)) {rspeak(42); return; }
- rspeak(12);
- return;
- }
-
- static struct cvloc *
- leave(tr) register struct cvtrav *tr;
- {
- if (tr->l <= 300) return &(cvloc[tr->l]) ;
- if (tr->l <= 500)
- switch (tr->l)
- {
- case 301: /* wrong magic word ! */
- newloc = loc;
- switch (SHELF->prop) {
- case 0:
- shakeit: if (loc - cvloc == SHELF->iloc || loc - cvloc == SHELF->iloc+1)
- rspeak(214);
- else
- rspeak(162);
- SHELF->prop ++ ;
- return loc;
- case 1:
- if (PCT(25)) goto shakeit;
- if (PCT(33)) {
- rspeak(42);
- return loc;
- }
- SHELF->prop++;
- { register struct cvobj *ob;
- register struct cvloc *shloc;
- shloc = &(cvloc[SHELF->iloc]);
-
- /* dump everything off of shelf */
- for (ob = lastobj; ob != cvobj; ob--) {
- if (ob->conn1.where == shloc) move(ob,shloc+1);
- }
- move2(SHELF,shloc); /* shelf stays, though */
- if (!AT(SHELF)) {
- rspeak(162);
- return loc;
- }
- loc = shloc + 1;
- newloc = &(cvloc[25]);
- rspeak(163);
- return loc;
- }
- case 3: /* already destroyed */
- rspeak(42);
- return loc;
- }
- case 302: /* down a clean column */
- loc = COLUMN->conn1.where;
- if (COLUMN->prop == 0) {
- COLUMN->prop = 1;
- if (DAM->prop == 0) {
- loc = &(cvloc[getrick()]);
- }
- }
- return loc;
- case 303: /* out of maze .. activate grendl if carrying orb */
- newloc = loc - 1;
- SPIDER->prop = 0;
- pspeak(SPIDER,2);
- GRENDL->dseen = TRUE;
- GRENDL->dloc = newloc;
- return newloc;
- case 305: /* jumped into bottomless fissure */
- rspeak(224);
- { register struct cvobj *ob;
- register int co;
- co = 0;
- for (ob = cvobj; ob->desc != NULL; ob++) {
- if (TOTING(ob)) {co++; destry(ob);}
- }
- if (RUG->prop == 1) RUG->prop = 0;
- rspeak(co ? 134 : 133);
- }
- loc = newloc = oldlc2 = &(cvloc[62]);
- return loc;
- case 306: /* leave repository */
- newloc = &(cvloc[146]);
- if (MIRROR->prop == 1) {
- MIRROR->prop = 0;
- pspeak(MIRROR,2);
- ME->dloc = loc;
- ME->dseen = TRUE;
- }
- return loc;
- default: bug(20);
- }
- rspeak((int)(tr->l - 500)) ;
- return loc ;
- }
-
- #define SKIP {ctrav = skip(ctrav); continue; }
- #define DOIT { register struct cvloc *temp; temp = leave(ctrav) ;\
- if (ctrav->s) continue ; else return temp; }
- static struct cvtrav *
- skip(tr) register struct cvtrav *tr;
- { while (tr->s) {++tr;} ;
- return tr ;
- }
-
- /* given the current location in parameter "where" and a verb in parameter
- * "verb", put the new location into the result. The current loc is saved
- * in "oldloc" in case he wants to retreat. The current "oldloc" is saved
- * in "oldlc2", in case he dies. (If he does, "newloc" will be limbo, and
- * "oldloc" will be what killed him, so we need "oldlc2", which is the
- * last place he was safe.)
- *
- * Each location (struct cvloc) has a travel array (struct cvtrav *travel)
- * of entries, each of which contains a word-number (or -1 to end the
- * array for this location) and maybe some other stuff. If the location
- * and continue parts are both zero, subsequent entries are examined until
- * a useable one is found (this makes several motion words synonyms in the
- * location). The continue flag makes for concatenated decisions, or for
- * messages then motions, all in one entry, without the need for fake
- * forced-motion locations. (e.g. AHHHHHHHHH...You are at the bottom with
- * a broken neck).
- */
-
- struct cvloc *
- moveme(where,verb) struct cvloc *where; int verb;
- {
- register struct cvtrav *ctrav;
- auto int rugrop;
-
- /* if he tries to use the compass, make sure this makes sense */
- if ( (verb >= NORTH) && (verb <= NW))
- { if (where > (&(cvloc[30])) && !TOTING(COMPASS) )
- { rspeak(58); return where; } /* need compass */
-
- if (DARK)
- { rspeak(74) ; return where; } /* can't read compass */
- }
-
- if (verb == WAIT) { return where; }
-
- if (verb == BACK)
- {
- /* look for a verb which goes from where to oldloc,
- or if oldloc has forced motion, to oldlc2. If one is found,
- and the verb is not magic, and does not involve random motion,
- he can go back. */
-
- register struct cvloc *backto;
- register struct cvtrav *forceto ;
- register int fword;
-
- backto = FORCED(oldloc) ? oldlc2 : oldloc ;
- oldlc2 = oldloc ; oldloc = where ;
-
- if ( (backto == where) || PCT(5) )
- { rspeak(91); return where; }
-
- for (forceto = NULL,
- ctrav = where->travel; ctrav->word >= 0; ++ctrav)
- { if ((&(cvloc[ctrav->l])) == backto) {forceto = ctrav; break ; }
- if (ctrav->l < 300)
- { register struct cvloc *through;
- through = &(cvloc[ctrav->l]) ;
- if (FORCED(through)
- && ((&(cvloc[through->travel->l])) == backto))
- forceto = ctrav ;
- }
- }
-
- if (forceto == NULL)
- { rspeak(140); /* you can't get there from here */
- return where;
- }
-
- fword = forceto->word ;
- /* make him find his own magic words */
- if ( (fword == HOPE)
- || (fword == BANIS)
- || (fword == MISFO) )
- { rspeak(91); return where; }
-
- /* don't go back through probabilities, or other conditions */
- for (ctrav = where->travel; ctrav->word >= 0; ++ctrav)
- { if ( (ctrav->word == fword) && (ctrav->n))
- { rspeak(91); return where; }
- }
- verb = fword ; /* change verb to the one that does it */
- }
-
- oldlc2 = oldloc; oldloc = where;
-
- switch (verb)
- {
- case DOWN: rugrop = 1 ; break ;
- case UP: rugrop = 2 ; break ;
- case CLIMB: rugrop = 3 ; break ;
- default: rugrop = 0 ; break ;
- }
-
- /* find an entry with this motion verb */
- for (ctrav = where->travel; ctrav->word >= 0; ++ctrav)
- { if ((ctrav->word == 1) || (ctrav->word == verb)) break ;
- }
-
- if (ctrav->word < 0)
- { /* no such motion -- unless we can find a way to do it with the
- rug or the rope */
- if (rugrop) {
- register int l, len;
- register struct rtr *rtrp;
- l = loc - cvloc;
- len = 0;
- for (rtrp = rtrav; rtrp->top > 0; rtrp++) {
- switch (rugrop) {
- case 3: /* he said "CLIMB" */
- if (rtrp->top == l) goto down;
- if (rtrp->bot == l) goto up;
- if (rtrp->mid == l) goto up;
- case 1: /* he said "DOWN" */
- down:
- if (rtrp->mid == l) {
- if (rtrp->bot) {
- l = rtrp->bot;
- len = 1;
- }
- } else if (rtrp->top == l) {
- if (rtrp->mid) {
- l = rtrp->mid;
- len = 1;
- } else {
- l = rtrp->bot;
- len = 2;
- }
- }
- break;
- case 2: /* he said "UP" */
- up:
- if (rtrp->mid == l) {
- l = rtrp->top;
- len = 1;
- } else if (rtrp->bot == l) {
- if (rtrp->mid) {
- l = rtrp->mid;
- len = 1;
- } else {
- l = rtrp->top;
- len = 2;
- }
- }
- break;
- } /* end switch */
- /* l = possible destination number */
- /* len = # of 60-foot rope segments needed */
- if (len) break;
- } /* end for to find destination */
- if (len) {
- newloc = &(cvloc[l]);
- if (RUG->prop == 1 && rugrop != 3) { /* flying? */
- if (rtrp->rug) {
- rspeak(199); /* flying where he shouldn't */
- move(RUG, &(cvloc[RUG->iloc]));
- oldlc2 = &(cvloc[rtrp->drop]);
- die();
- }
- return newloc;
- } /* end of flying */
- if (ROPE->conn1.where - cvloc == rtrp->top) {
- l = ROPE->prop;
- if (l % 2) goto L6345;
- }
- if (ROPE2->conn1.where - cvloc == rtrp->top) {
- l = ROPE2->prop;
- if (l == 3) goto L6345;
- }
- /* check that you have the rope or carpet set up */
- L6340: if (rtrp == rtrav) {
- if (PCT(20)) return loc;
- loc = DEAD;
- newloc = &(cvloc[24]);
- return newloc;
- }
- newloc = loc;
- if (RUG->prop == 0 && PCT(67)) rspeak(198);
- else rspeak(14);
- return newloc;
- L6345:
- switch (l) {
- case 3: /* 60 foot rope */
- if (len > 1) {
- rspeak(153);
- return loc;
- }
- case 1: /* 120 foot rope, uncut */
- case 7: /* 120 foot rope, spliced and tested */
- L6350: if (RUG->prop == 1) {
- newloc = loc;
- rspeak(117);
- }
- return newloc;
- case 5: /* 120 foot rope with a dangerous knot */
- if (RUG->prop == 1) {
- rspeak(117);
- return loc;
- }
- if (loc == &(cvloc[rtrp->bot]) ||
- newloc == &(cvloc[rtrp->bot])) {
- rspeak(208);
- ROPE->prop = 3; /* broken rope */
- EROPE->prop = 0;
- destry(EROPE2);
- move(ROPE2,&(cvloc[rtrp->drop]));
- ROPE2->prop = 2;
- oldlc2 = &(cvloc[rtrp->drop]);
- die();
- return newloc;
- }
- goto L6350;
- default:
- bug(55);
- } /* end of rope-state switch */
- } else {
- newloc = loc;
- }
- } /* end of rug/rope possibilities */
- wrongway(verb); return where;
- }
-
- do
- {
- for (;!(ctrav->s) && !(ctrav->l) && !(ctrav->n);++ctrav) ;
-
- switch (ctrav->m)
- {
- case 0:
- if ((ctrav->n) && !PCT(ctrav->n)) SKIP ;
- DOIT ;
- case IF_HAVE:
- if (!TOTING(OBJ(ctrav->n))) SKIP ;
- DOIT ;
- case IF_NHAVE:
- if (TOTING(OBJ(ctrav->n))) SKIP ;
- DOIT ;
- case IF_WITH:
- if (!HERE(OBJ(ctrav->n))) SKIP ;
- DOIT ;
- case IF_NWITH:
- if (HERE(OBJ(ctrav->n))) SKIP ;
- DOIT ;
- case IF_PROP:
- if (OBJ(ctrav->n)->prop != ctrav->v) SKIP ;
- DOIT ;
- case IF_NPROP:
- if (OBJ(ctrav->n)->prop == ctrav->v) SKIP ;
- DOIT ;
- }
- bug(29) ;
- } while ((++ctrav)->word >= 0) ;
-
- bug(25) ;
- return where;
- }
-